import yagmail
import time
import re
import smtplib
from typing import Union, List, Optional, Tuple
# 需要安装依赖：pip install dnspython
import dns.resolver

class QQMailSender:
    def __init__(self, user: str, password: str, max_retries: int = 3):
        """
        初始化邮件发送客户端
        :param user: QQ邮箱地址（如 '123456@qq.com'）
        :param password: SMTP授权码（非登录密码）
        :param max_retries: 发送失败时的最大重试次数
        """
        self.user = user
        self.password = password
        self.max_retries = max_retries
        self.yag = self._init_smtp_client()

    def _init_smtp_client(self) -> yagmail.SMTP:
        """初始化SMTP客户端，支持自动重连"""
        try:
            return yagmail.SMTP(
                user=self.user,
                password=self.password,
                host='smtp.qq.com',
                port=465,
                smtp_ssl=True,
                smtp_skip_login=False  # 强制验证SMTP连接
            )
        except smtplib.SMTPAuthenticationError as e:
            raise ValueError("SMTP认证失败，请检查邮箱和授权码") from e

    def validate_email_format(self, email: str) -> bool:
        """
        验证邮箱格式是否合法（正则表达式）
        :param email: 待验证的邮箱地址
        :return: True表示格式合法
        """
        pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
        return re.match(pattern, email) is not None

    def validate_email_available(self, email: str) -> bool:
        """
        验证邮箱的域名是否在指定的域名列表中
        :param email: 待验证的邮箱地址
        :return: True表示域名合法
        """
        return True

    def send(
            self,
            to: Union[str, List[str]],
            subject: str,
            contents: Union[str, List[str]],
            attachments: Optional[List[str]] = None,
            retry: bool = True
    ) -> dict:
        """
        发送邮件（支持重试和异常捕获）,横着写不开了,将参数列表竖着写了
        :param to: 收件人（单个或多个）
        :param subject: 邮件主题
        :param contents: 邮件正文（支持HTML和纯文本）
        :param attachments: 附件路径列表
        :param retry: 是否启用失败重试
        :return: 包含状态和详情的字典
        """
        result = {'status': 'failed', 'to': to, 'timestamp': time.ctime()}

        for attempt in range(1, self.max_retries + 1):
            try:
                self.yag.send(
                    to=to,
                    subject=subject,
                    contents=contents,
                    attachments=attachments
                )
                result.update({
                    'status': 'success',
                    'attempts': attempt,
                    'message': '邮件发送成功'
                })
                break
            except Exception as e:
                result['message'] = f"Attempt {attempt}: {str(e)}"
                if not retry or attempt == self.max_retries:
                    break
                time.sleep(2 ** attempt)  # 指数退避重试
                self.yag = self._init_smtp_client()  # 重建连接

        return result

    def close(self):
        """关闭SMTP连接"""
        if hasattr(self, 'yag') and self.yag:
            self.yag.close()

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.close()


if __name__ == '__main__':
    # 使用示例
    with QQMailSender('jiyunfeng_siwu@qq.com', 'royqmkaipbzoebid') as sender:
        # 验证邮箱
        test_email = '2601727296@qq.com'
        if sender.validate_email_format(test_email):
            print(f"邮箱格式验证通过: {test_email}")


        # # 发送邮件
        # result = sender.send(
        #     to=test_email,
        #     subject='封装测试,邮箱发送测试:to->lxc :)',
        #     contents=[
        #         '<h1>:)</h1>',
        #         yagmail.inline('火狐doge.jpg')  # 内嵌图片
        #     ],
        #     attachments=['项目git提交流程(含命令).pdf']
        # )
        # print("发送结果:", result)